package api

import (
	"bookProject/entity"
	"bookProject/global"
	user "bookProject/proto"
	"bookProject/vender/jwt"
	"context"
	"crypto/md5"
	"fmt"
	"github.com/anaskhan96/go-password-encoder"
	jwt2 "github.com/dgrijalva/jwt-go/v4"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"time"
)

type User struct {
	Username string
	Password string
	Mobile   string
	Email    string
	Sex      int
	Salt     string
}

// 用户注册接口
func UserRegister(ctx *gin.Context) {
	registerForm := entity.RegisterForm{}
	//参数校验
	err := ctx.ShouldBind(&registerForm)
	if err != nil {
		zap.S().Error(err)
		ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	options := &password.Options{global.GlobalConfig.SaltMd5.SaltLen, global.GlobalConfig.SaltMd5.Iterations, global.GlobalConfig.SaltMd5.KeyLen, md5.New}
	salt, encodedPwd := password.Encode(registerForm.PassWord, options)
	fmt.Println(salt)
	info, err := mysqlToPb(&User{
		Username: registerForm.Name,
		Password: encodedPwd,
		Mobile:   registerForm.Mobile,
		Salt:     salt,
		Email:    registerForm.Email,
		Sex:      registerForm.Sex,
	})
	fmt.Println(info)
	data, err := global.UserClient.CreateUser(context.Background(), &user.CreateReq{
		Info: info,
	})
	if err != nil {
		panic(err)
	}
	ctx.JSON(200, gin.H{
		"msg":     "请求成功",
		"data":    data,
		"success": true,
	})
}

// 用户登陆接口
func UserLogin(ctx *gin.Context) {
	loginForm := entity.LoginForm{}
	//参数校验
	err := ctx.ShouldBind(&loginForm)
	if err != nil {
		zap.S().Error(err)
		ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	//userInfo, err := global.UserClient.GetUserByUsername(context.Background(), &user.GetUserByUsernameReq{Username: loginForm.Name})
	//密码校验--根据用户名返回用户信息  1.-- 可复用性  2.非必要参数不要传   3.非必要参数不要返
	userInfo, err := global.UserClient.GetUserByUsername(context.Background(), &user.GetUserByUsernameReq{Username: loginForm.Name})
	if err != nil {
		zap.S().Error(err)
		ctx.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
		return
	}
	zap.S().Info("密码校验返回结果::::", userInfo)
	//校验
	options := &password.Options{global.GlobalConfig.SaltMd5.SaltLen, global.GlobalConfig.SaltMd5.Iterations, global.GlobalConfig.SaltMd5.KeyLen, md5.New}
	check := password.Verify(loginForm.PassWord, userInfo.Info.Salt, userInfo.Info.Password, options)
	if !check {
		zap.S().Info("用户登陆时密码校验不通过")
		ctx.JSON(http.StatusBadRequest, gin.H{"msg": "密码校验不通过"})
		return
	}

	//jwt token生成
	token, err := jwt.CreateToken(&jwt.MyCustomClaims{
		//存储用户ID
		UserId: userInfo.Info.Id,
		//过期时间
		StandardClaims: jwt2.StandardClaims{
			ExpiresAt: jwt2.NewTime(float64(time.Now().Unix() + 86400)),
		},
	})
	results := map[string]string{}
	results["token"] = token
	ctx.JSON(200, gin.H{
		"data": results,
		"code": "success",
	})
	//ctx.JSON(http.StatusOK, &gin.H{
	//	"msg":  "success",
	//	"code": 1,
	//	"data": map[string]interface{}{
	//		"userInfo": userInfo.Info,
	//		"token":    token,
	//	},
	//})
}

func mysqlToPb(info *User) (*user.UserInfo, error) {
	return &user.UserInfo{
		Username: info.Username,
		Password: info.Password,
		Email:    info.Email,
		Mobile:   info.Mobile,
		Sex:      user.Sex(info.Sex),
		Salt:     info.Salt,
	}, nil
}
